﻿/************************************************************************
 * CoreDES - A small and core library for discrete event systems
 * Copyright (C) 2012-2013 Ali Khalili (khalili_DOT_ir_@SIGN_gmail_DOT_com)
 * **********************************************************************
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License (LGPL) published 
 * by the Free Software Foundation; either version 2.1 of the License, or (at your
 * option) any later version. This program is distributed without any
 * warranty. See the GNU Lesser General Public License for more details. 
 * ***********************************************************************
 * File         :     CoreDES\Execution\ExecutableMethod.cs
 * Description  :     a wrapper for System.Reflection.MethodInfo
 * Change log   :     -oct 2013: initial version
 * To Do        :
 ************************************************************************/
using System;
using System.Reflection;

namespace CoreDES.Execution
{
    /// <summary>
    /// Any executable method. In fact, it is a wrapper for System.Reflection.MethodInfo
    /// </summary>
    public class ExecutableMethod
    {
        /// <summary>
        /// Constructor (for childrens)
        /// </summary>
        protected ExecutableMethod()
        {
            //* nothing!
        }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="handler">the handler of the executable method</param>
        /// <param name="target">the target object</param>
        public ExecutableMethod(MethodInfo handler, object target = null)
        {
            this.handler = handler;
            if (target != null)
            {
                this.target = target;
            }
        }

        /// <summary>
        /// The method is executable on an object or not
        /// </summary>
        public bool IsExecutable
        {
            get
            {
                return (handler != null && target != null);
            }
        }


        /// <summary>
        /// ID of the method (name of method)
        /// </summary>
        public string ID
        {
            get
            {
                return handler.Name;
            }
        }

        /// <summary>
        /// Its handle
        /// </summary>
        public MethodInfo info
        {
            get
            {
                return this.handler;
            }
        }

        /// <summary>
        /// The target object
        /// </summary>
        protected object target;

        /// <summary>
        /// Signiture of the function
        /// </summary>


        /// <summary>
        /// handler to the function (to execute the function)
        /// </summary>
        protected MethodInfo handler;

        /// <summary>
        /// Execute the method
        /// </summary>
        /// <param name="parameters">parameters of the methor</param>
        /// <returns>the return value</returns>
        public object Execute(params object[] parameters)
        {
            if (target == null)
                throw new Exception("The target object is NULL!");

            return handler.Invoke(target, parameters);
        }

        /// <summary>
        /// Execute the method in static mode
        /// </summary>
        /// <param name="parameters">parameters of the methor</param>
        /// <returns>the return value</returns>
        public object ExecuteStatic(params object[] parameters)
        {
            return handler.Invoke(null, parameters);
        }
    }
}
